package com.qianniu.napi.admin.web;

import akka.actor.ActorRef;
import akka.actor.Props;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.github.stuxuhai.jpinyin.PinyinFormat;
import com.github.stuxuhai.jpinyin.PinyinHelper;
import com.google.common.base.Strings;
import com.qianniu.napi.admin.entity.*;
import com.qianniu.napi.admin.entity.penum.*;
import com.qianniu.napi.admin.service.*;
import com.qianniu.napi.admin.service.akka.AkkaServer;
import com.qianniu.napi.admin.service.akka.FanActor;
import com.qianniu.napi.admin.service.akka.ResourceActor;
import com.qianniu.napi.admin.service.akka.StoreActor;
import com.qianniu.napi.common.config.Constants;
import com.qianniu.napi.common.util.*;
import io.swagger.models.auth.In;
import javafx.collections.ObservableMap;
import org.apache.ibatis.annotations.Param;
import org.opencv.face.BIF;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.support.CustomSQLErrorCodesTranslation;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * <p>
 * </p>
 *
 * @author chenxuebin
 * @since 2018-06-15
 */
@RestController
public class DduozhuanController {

    private static final Logger logger = LoggerFactory.getLogger(DduozhuanController.class);

    @Autowired
    private IAccountService accountService;
    @Autowired
    private IRedisService redisService;
    @Autowired
    private IWeixinService weixinService;
    @Autowired
    private IJifenService jifenService;
    @Autowired
    private IJifenFlowService jifenFlowService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IFensService fensService;
    @Autowired
    private IXnbiService xnbiService;
    @Autowired
    private ISigninService signinService;
    @Autowired
    private IAccountTixianService accountTixianService;
    @Autowired
    private IAccountFlowService accountFlowService;

    /**
     * 微信授权登录
     *
     * @param code 授权临时票据
     * @return map
     * @throws Exception
     */
    @RequestMapping(value = "/api/ddz/wxlogin", method = RequestMethod.POST)
    @ResponseBody
    public Jinfo weChatLogin(@RequestParam("code") String code,
                             @RequestParam(value = "guid", required = false) String guid) {

        Jinfo info = new Jinfo();

        try {
            Map<String, Object> map = weixinService.wxappLogin(code, guid, ObjectUtil.getMpid());
            info.setData(map);
        } catch (Exception e) {
            info.setCode(4);
            info.setMsg(e.getMessage());
        }
        logger.debug("==========/api/ddz/wxlogin info=" + JSON.toJSONString(info));
        return info;
    }

    /**
     * 个人用户信息
     *
     * @return map
     * @throws Exception
     */
    @RequestMapping(value = "/api/ddz/userbase", method = RequestMethod.GET)
    @ResponseBody
    public Jinfo weChatLogin() {
        Jinfo info = new Jinfo();
        if (ObjectUtil.getUid() == null) {
            info.setCode(4);
            info.setMsg("用户未登录");
            return info;
        }
        Long uid = ObjectUtil.getUid();

        Map map = new HashMap<String, Object>();

        Jifen jifen = jifenService.selectOne(new EntityWrapper<Jifen>().eq("uid", uid));
        if (jifen != null) map.put("jifen", jifen.getTotal());
        else map.put("jifen", 0);

        Account account = accountService.selectOne(new EntityWrapper<Account>()
                .eq("uid", uid));
        if (account != null) map.put("money", account.getAmount());
        else map.put("money", 0);

        info.setData(map);
        logger.debug("==========/api/ddz/userbase info=" + JSON.toJSONString(info));
        return info;

    }

    /**
     * 绑定推荐人关系
     *
     * @return map
     * @throws Exception
     */
    @RequestMapping(value = "/api/ddz/bindtcode", method = RequestMethod.GET)
    @ResponseBody
    public Jinfo bindtcode(@RequestParam("tcode") String tcode) {
        Jinfo info = new Jinfo();

        if (ObjectUtil.getUid() == null) {
            info.setCode(4);
            info.setMsg("用户未登录");
            return info;
        }

        Long uid = ObjectUtil.getUid();
        Long mpid = ObjectUtil.getMpid();
        User user = redisService.getUser();
        if (!Strings.isNullOrEmpty(user.getGenlink())) {
            info.setCode(4);
            info.setMsg("您已绑定过推荐关系");
            return info;
        }
        Date now = new Date();
        boolean outer7 = (now.getTime() - user.getCreatetime().getTime()) / 1000 / 3600 / 24 >= 3;
        if (outer7) {
            info.setCode(4);
            info.setMsg("您注册时间超过72小时无法绑定");
            return info;
        }

        User puser = userService.selectOne(new EntityWrapper<User>()
                .eq("tcode", tcode)
                .eq("mpid", ObjectUtil.getMpid()));
        if (puser == null) {
            info.setCode(4);
            info.setMsg("该邀请码无效");
            return info;
        }
        if (puser.getId().longValue() == uid.longValue()) {
            info.setCode(4);
            info.setMsg("无法绑定自己的邀请码");
            return info;
        }

        Long puid = puser.getId();
        // 用户更新推荐基因链
        String genlink = puser == null ? "0" : (puser.getGenlink() == null ? "0#" + puid : puser.getGenlink() + "#" + puid);
        User upuser = new User();
        upuser.setId(uid);
        upuser.setModifytime(new Date());
        user.setGenlink(genlink);
        user.updateById();

        //插入粉丝关系，默认二级关系
        Fens fens = new Fens();

        fens.setUid(user.getId());
        fens.setGuid(user.getGuid());

        fens.setNickname(user.getNickName());
        fens.setAvatarpic(user.getAvatarPic());
        fens.setPuid(puser.getId());

        fens.setLevelType(1);
        fens.setStatus(1);
        fens.setState(1);

        fens.setOriginType(2);//邀请码
        fens.setYwid(tcode);

        fens.setMid(user.getMid());
        fens.setMpid(user.getMpid());
        fens.setCreatetime(new Date());
        fens.insert();

        logger.debug("---------------------------1th fensi insert OK");

        // =========== 返奖励给上一级(1级返赠送) ===========
        FanConfig fconfig = redisService.getFanconfig(ObjectUtil.getMpid());
        if (fconfig == null) {
            logger.info("-------------------------------registFan fconfig is null");
            return info;
        }

        BigDecimal fan = fconfig.getNuserfanMount();
        Integer type = fconfig.getNuserfanType();

        if (type != null && type.intValue() == XffanType.jifen.getVal()) {

            jifenService.addJifenFlow(puid, user.getMid(), mpid,
                    fan, true, FantimeType.now.getVal(),
                    StringUtil.getSnNo(), IotypeEnum.input, JftypeEnum.share, tcode, 0l);
        } else if (type != null && type.intValue() == XffanType.xnbi.getVal()) {

            xnbiService.addXnbiFlow(puid, user.getMid(), mpid,
                    fan, true, FantimeType.now.getVal(),
                    StringUtil.getSnNo(), IotypeEnum.input, JftypeEnum.share, tcode, 0l);
        } else if (type != null && type.intValue() == XffanType.qian.getVal()) {

            accountService.addAccountFlow(puid, user.getMid(), mpid,
                    fan, true, FantimeType.now.getVal(),
                    StringUtil.getSnNo(), IotypeEnum.input, XftypeEnum.sharefan, tcode, 0l);
        }

        //判断二级粉丝
        Fens pfens = fensService.selectOne(new EntityWrapper<Fens>()
                .eq("uid", puser.getId()).eq("level_type", 1));
        if (pfens != null) {
            User ppuser = userService.selectById(pfens.getPuid());
            fens.setId(null);
            fens.setPuid(ppuser.getId());
            fens.setLevelType(2);
            fens.insert();

            BigDecimal fan2 = fconfig.getNuserfanMount2();
            Integer type2 = fconfig.getNuserfanType2();

            if (type2 != null && type2.intValue() == XffanType.jifen.getVal()) {

                jifenService.addJifenFlow(ppuser.getId(), user.getMid(), mpid,
                        fan2, true, FantimeType.now.getVal(),
                        StringUtil.getSnNo(), IotypeEnum.input, JftypeEnum.share2, tcode, 0l);

            } else if (type2 != null && type2.intValue() == XffanType.xnbi.getVal()) {

                xnbiService.addXnbiFlow(ppuser.getId(), user.getMid(), mpid,
                        fan2, true, FantimeType.now.getVal(),
                        StringUtil.getSnNo(), IotypeEnum.input, JftypeEnum.share2, tcode, 0l);

            } else if (type2 != null && type2.intValue() == XffanType.qian.getVal()) {

                accountService.addAccountFlow(ppuser.getId(), user.getMid(), mpid,
                        fan2, true, FantimeType.now.getVal(),
                        StringUtil.getSnNo(), IotypeEnum.input, XftypeEnum.sharefan, tcode, 0l);

            }
        }

        HashMap<String, Integer> jtmap = new HashMap<String, Integer>();
        List<Integer> jtlist = new ArrayList<>();
        if (!Strings.isNullOrEmpty(fconfig.getNuserjtfan())) {

            String[] jtfan = fconfig.getNuserjtfan().split("#");
            for (String item : jtfan) {
                String[] itemarr = item.split("-");
                jtlist.add(Integer.valueOf(itemarr[0]));
                jtmap.put("jieti_" + itemarr[0], Integer.valueOf(itemarr[1]));
            }

            //要求直推多少
            int tcout = fensService.selectCount(new EntityWrapper<Fens>()
                    .eq("uid", puid).eq("level_type", 1));
            boolean flag = false;
            for (Integer jieti : jtlist) {
                if (tcout == jieti) {
                    flag = true;
                    break;
                }
            }

            //满足阶梯触发条件
            if (flag == true) {
                BigDecimal fanmout = new BigDecimal(jtmap.get("jieti_" + tcout));
                Integer jttype = fconfig.getNuserjtfanType();

                if (jttype.intValue() == XffanType.jifen.getVal()) {

                    jifenService.addJifenFlow(puid, user.getMid(), mpid,
                            fanmout, true, FantimeType.now.getVal(),
                            StringUtil.getSnNo(), IotypeEnum.input, JftypeEnum.share, tcode, 0l);
                } else if (jttype.intValue() == XffanType.xnbi.getVal()) {

                    xnbiService.addXnbiFlow(puid, user.getMid(), mpid,
                            fanmout, true, FantimeType.now.getVal(),
                            StringUtil.getSnNo(), IotypeEnum.input, JftypeEnum.share, tcode, 0l);
                } else if (jttype.intValue() == XffanType.qian.getVal()) {

                    accountService.addAccountFlow(puid, user.getMid(), mpid,
                            fanmout, true, FantimeType.now.getVal(),
                            StringUtil.getSnNo(), IotypeEnum.input, XftypeEnum.sharefan, tcode, 0l);
                }
            }
        }
        logger.debug("==========/api/ddz/bindtcode info=" + JSON.toJSONString(info));
        return info;
    }

    @RequestMapping("/api/ddz/fenslist")
    @ResponseBody
    public Jinfo fenslist() {
        Jinfo info = new Jinfo();
        if (ObjectUtil.getUid() == null) {
            info.setCode(4);
            info.setMsg("用户未登录");
            return info;
        }

        Long uid = ObjectUtil.getUid();

        Map<String, Object> map = new HashMap<String, Object>();
        Page page = new Page(1, 100);

        Page<Fens> fs1 = fensService.selectPage(page, new EntityWrapper<Fens>()
                .setSqlSelect("id,uid,puid,nickname,avatarpic")
                .eq("puid", uid)
                .eq("level_type", 1)
                .eq("state", 1));
        map.put("fs1list", fs1.getRecords());
        map.put("fs1cout", fensService.selectCount(new EntityWrapper<Fens>()
                .eq("puid", uid)
                .eq("level_type", 1)
                .eq("state", 1)));

        Page<Fens> fs2 = fensService.selectPage(page, new EntityWrapper<Fens>()
                .setSqlSelect("id,uid,puid,nickname,avatarpic")
                .eq("puid", uid)
                .eq("level_type", 2)
                .eq("state", 1));

        map.put("fs2list", fs2.getRecords());
        map.put("fs2cout", fensService.selectCount(new EntityWrapper<Fens>()
                .eq("puid", uid)
                .eq("level_type", 2)
                .eq("state", 1)));

        info.setData(map);
        return info;

    }

    //好友赚
    @RequestMapping("/api/ddz/haouzhuan")
    @ResponseBody
    public Jinfo haouzhuan() {

        Jinfo info = new Jinfo();
        if (ObjectUtil.getUid() == null) {
            info.setCode(4);
            info.setMsg("用户未登录");
            return info;
        }

        Long uid = ObjectUtil.getUid();

        Map<String, Object> map = new HashMap<String, Object>();
        Page page = new Page(1, 100);

        //一级好友数
        int fs1cout = fensService.selectCount(new EntityWrapper<Fens>()
                .eq("puid", uid)
                .eq("level_type", 1)
                .eq("state", 1));
        map.put("fs1cout", fs1cout);

        //二级好友数
        int fs2cout = fensService.selectCount(new EntityWrapper<Fens>()
                .eq("puid", uid)
                .eq("level_type", 2)
                .eq("state", 1));
        map.put("fs2cout", fs2cout);

        //好友数总数
        map.put("fscout", fs1cout + fs2cout);

        JifenFlow flow1 = jifenFlowService.selectOne(new EntityWrapper<JifenFlow>().setSqlSelect("sum(num) num")
                .eq("uid", uid).eq("jftype", JftypeEnum.share.getVal()));

        JifenFlow flow2 = jifenFlowService.selectOne(new EntityWrapper<JifenFlow>().setSqlSelect("sum(num) num")
                .eq("uid", uid).eq("jftype", JftypeEnum.share2.getVal()));

        //一级好友数贡献金额
        BigDecimal fs1money = flow1 == null || flow1.getNum() == null ? new BigDecimal(0) : flow1.getNum();
        map.put("fs1money", fs1money);
        //一级好友数贡献金额
        BigDecimal fs2money = flow2 == null || flow2.getNum() == null ? new BigDecimal(0) : flow2.getNum();
        map.put("fs2money", fs2money);
        map.put("fsmoney", fs1money.add(fs2money));

        //收入排名
        List<AccountFlow> paiming = accountFlowService.selectList(new EntityWrapper<AccountFlow>()
                .setSqlSelect("amount,total,nickname,headimg")
                .eq("mpid", -1).orderBy("amount", false));

        map.put("paiming", paiming);

        info.setData(map);
        return info;

    }


    //好友赚首页接口
    @RequestMapping("/api/ddz/hindex")
    @ResponseBody
    public Jinfo hindex() {

        Jinfo info = new Jinfo();
        if (ObjectUtil.getUid() == null) {
            info.setCode(4);
            info.setMsg("用户未登录");
            return info;
        }

        Long uid = ObjectUtil.getUid();

        Map<String, Object> map = new HashMap<String, Object>();
        MerchantConfig mconfig = redisService.getMconfig();

        //当日送币金额
        map.put("songbi", mconfig.getAboutType());
        Jifen jifen = jifenService.selectOne(new EntityWrapper<Jifen>().eq("uid", uid));
        //当前积分总数
        map.put("jifen", jifen.getTotal());

        //已提现额
        AccountTixian act = accountTixianService.selectOne(new EntityWrapper<AccountTixian>()
                .setSqlSelect("sum(money) money")
                .eq("uid", uid).eq("txtype", 1).eq("status", 2));
        map.put("tixian", act == null || act.getMoney() == null ? 0 : act.getMoney());

        int cout = signinService.selectCount(new EntityWrapper<Signin>()
                .eq("uid",uid).eq("stype",-1)
                .eq("pdate",DateUtil.getToday()));

        //存钱罐被偷状态
        map.put("beitou", cout==0);

        info.setData(map);
        return info;

    }


    //存钱罐修复接口
    @RequestMapping("/api/ddz/ggxiufu")
    @ResponseBody
    public Jinfo ggxiufu() {

        Jinfo info = new Jinfo();
        if (ObjectUtil.getUid() == null) {
            info.setCode(4);
            info.setMsg("用户未登录");
            return info;
        }

        Signin signin = new Signin();
        signin.setLianxu(0);
        signin.setPdate(DateUtil.getToday());
        signin.setStype(-1);
        signin.setSignintime(new Date());

        signin.setMid(ObjectUtil.getMid());
        signin.setMpid(ObjectUtil.getMpid());
        signin.setUid(ObjectUtil.getUid());

        signin.insert();

        return info;

    }

    //首页领取金币积分接口
    @RequestMapping(value = "/api/ddz/jblingqu", method = RequestMethod.POST)
    @ResponseBody
    public Jinfo jblingqu(@RequestParam("jbshu") Integer jbshu) {

        Jinfo info = new Jinfo();
        Long uid = ObjectUtil.getUid();
        if (uid == null) {
            info.setCode(4);
            info.setMsg("用户未登录");
            return info;
        }
        Long mid = ObjectUtil.getMid();
        Long mpid = ObjectUtil.getMpid();

        jifenService.addJifenFlow(uid, mid, mpid,
                BigDecimal.valueOf(jbshu), true, FantimeType.now.getVal(),
                StringUtil.getSnNo(), IotypeEnum.input, JftypeEnum.lingqu, "金币积分领取", 0l);

        return info;

    }

    //每日签到
    @RequestMapping("/api/ddz/qiandao")
    @ResponseBody
    public Jinfo signinAdd(Signin signin) {
        Jinfo info = new Jinfo();
        if(ObjectUtil.getUid()==null){
            info.setCode(1);
            info.setMsg("请授权登录之后再签到");
            return info;
        }

        String pdate = DateUtil.getToday();
        String lastday = DateUtil.addToday(-1);
        Long uid = ObjectUtil.getUid();

        if (signin == null) signin = new Signin();
        Signin lastSignin = signinService.selectOne(new EntityWrapper<Signin>()
                .eq("uid", uid)
                .eq("pdate", lastday));
        if (lastSignin == null) {
            signin.setLianxu(1);
        } else {
            signin.setLianxu(lastSignin.getLianxu() + 1);
        }

        signin.setPdate(DateUtil.getToday());
        signin.setSignintime(new Date());

        signin.setMid(ObjectUtil.getMid());
        signin.setMpid(ObjectUtil.getMpid());
        signin.setUid(ObjectUtil.getUid());
        signin.insert();

        AkkaServer.system.actorOf(Props.create(FanActor.class))
                .tell(Constants.AKKA_MSG_SIGN_FAN + "@" + ObjectUtil.getUid() + "@" + ObjectUtil.getMpid(), ActorRef.noSender());

        return info;
    }

}
